import { Mesh, Vector3 } from "three"
import { Actor, GuandaoActor } from "./SceneLoader"

export enum WorkState {
    ANALYZ_MACHINE_PIPE,
    ANALYZ_PIPE,
    ANALYZ_MAIN_PIPE,
    FIX_PIPE_DIR,
    FIND_MACHINE_CONNECTED,
    ANALYZ_OTHER_PIPE,
    INIT_POINT,
    INIT_GRAPH,
    COLLISION_TEST,
    MERGE_POINT,
    FIX_RADIUS_MAP,
    DONE,
}

export type JsonOutActor = {
    id: string,
    sn: string,
    device: string,
    pos: number[],
    aabb: {
        min: number[],
        max: number[],
    }
}

export type JsonOutMachine = {
    actorid: number,
    sn: string,
    device: string,
    pos: number[],
    aabb: number[],
    in: number,
    out: number,
    type: string,
}

export type JsonOutPipe = {
    radiu: number,
    color: number
}

export type OutJson = {
    points: {[key: number]: JsonVirtualPipePoint}
    machine: JsonOutMachine[],
    pipes: {[key: number]: JsonOutPipe}
    pipeorder: string[]
    actors: {[key: number]: JsonOutPipe}
}

export enum PipeDir {
    UNKNOW,
    FORWARD,
    BACK,
}

export enum PointType {
    Port,
    TEE,
    PUMP,
    WATER,
}

export interface LinkInfo {
    from: GuandaoActor, //当前管道
    deviceid: string, // 连接的是机器的话，机器的id
    mesh: Mesh, // 连接的机器的网格
    actor: Actor,
}

export interface LinkInfoV2 {
    from: GuandaoActor, //当前管道
    pipe: GuandaoActor,
    node: VirtualPipePoint,
    replace?: boolean
}

export type BoxInfo = {
    min: Vector3,
    max: Vector3,
    name: string,
    mesh: Mesh,
}
export type JsonVirtualPipePoint = {
    id: number,
    pos: number[],
    out: number[],
    in: number[],
} 

export class VirtualPipePoint {
    static PipePointID = 0;
    //流向是input -> output
    //最多两个，流入管道
    private _id: number;
    in: VirtualPipePoint[] = [];
    out: VirtualPipePoint[] = [];
    //表示从in的点到当前控制点的管道示例
    pos: Vector3;
    //额外信息
    isMerged: boolean = false;
    constructor() {
        this._id = VirtualPipePoint.PipePointID++;
        this.pos = new Vector3();
    }

    //合并的点ID
    mergeId?: number;
    isChecked: boolean = false;
    unUsed: boolean = false;
    pointType: PointType = PointType.Port;
    userData?: any;
    get trueUsedId() {
        return this.mergeId ? this.mergeId : this.id;
    }

    get id() {
        return this._id;
    }

    toJson():JsonVirtualPipePoint {
        let out: number[] = [];
        this.out.forEach(p => {
            out.push(p.trueUsedId)
        })

        let inp: number[] = []
        this.in.forEach(p => {
            inp.push(p.trueUsedId)
        })

        return {
            id: this.trueUsedId,
            pos: this.pos.toArray(),
            out: out,
            in: inp,
        }
    }
}

export class VirtualMachinePart {
    outPipe?: VirtualPipe;
    inPipe?: VirtualPipe;
    deviceID: string = "";
    partType: "W" | "B" | "Unknow" = "Unknow"
    pipes: { pipe: GuandaoActor, idx: number }[] = [];
    nid: number = -1;
    actor?: Actor
}

export class VirtualPipe {
    pipe: GuandaoActor;
    pipeDir: PipeDir = PipeDir.UNKNOW;
    in?: VirtualMachinePart | VirtualPipe;
    out?: VirtualMachinePart | VirtualPipe;

    constructor(guandao: GuandaoActor, dir: PipeDir) {
        this.pipe = guandao;
        this.pipeDir = dir;
    }
}

export type ActorJsonList = {
    id: string, sn: string, device: string, pos: number[], aabb: {
        min: number[],
        max: number[],
    }
}[];